-- TransEliminateM
-- created by cheny3
-- 转换消除模块

module("TransEliminateM", package.seeall);

local trans_eliminate_table = {};

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    trans_eliminate_table = {};

    local trans_eliminate_CSV = get_trans_eliminate_CSV();
    for i = 1, #trans_eliminate_CSV do
        local row = trans_eliminate_CSV[i];

        trans_eliminate_table[row.id] = row;
    end
end

-- 模块初始化操作
function init()
    if not _init then
        loadCsv();

        rules = LOAD_PATH2("game/logic/module/trans_eliminate");
    end

    EventMgr.removeAll("TransEliminateM");
end

-- 获取子模块
function getModule(ruleName)
    local rule = rules[ruleName];
    if rule == "TBL" then
        rules[ruleName] = LOAD_RUN("game/logic/module/trans_eliminate/" .. ruleName);
        return rules[ruleName];
    end

    return rule;
end

-- 查询
function query(optionId, path)
    local m = trans_eliminate_table[optionId];

    if not m or not path then
        return m;
    end

    return m[path];
end

-- 点击某个元素
function clickElement(pos)
    if ME.user:isDead() then
        -- 玩家死掉了
        return false;
    end

    local grid = DungeonM.getGridByPos(pos);

    -- 如果不是消除格
    if grid.type ~= GRID_TYPE_TRANS_ELIMINATE or
        grid.state == GRID_STATE_DISABLE then
        trace("TransEliminateM", "不是转换消除格或已失效。");
        return false;
    end

    -- 格子的元素ID
    local transId = grid.trans_id;
    local info = query(transId);

    -- 找到子规则
    local rule = info["rule"];
    local ruleObject = getModule(rule);

    if not ruleObject then
        trace("TransEliminateM", "格子(%d/%d)没有子规则%s。", pos, tonumber(transId), tostring(rule));
        return false;
    end

    -- 交给子规则处理
    local ret = ruleObject.trigger(pos);

    -- 检查全清
    checkAllClear();

    -- 抛出一个回合事件
    EventMgr.fire(event.COMBAT_ROUND, pos);

    -- 抛出玩家出手
    EventMgr.fire(event.PLAYER_MOVE, pos);

    return ret;
end

-- 转换某个元素
function exchangeElement(pos)
    local grid = DungeonM.getGridByPos(pos);

    -- 如果不是消除格
    if grid.type ~= GRID_TYPE_TRANS_ELIMINATE or
        grid.state == GRID_STATE_DISABLE then
        -- trace("TransEliminateM", "不是转换消除格或已失效。");
        return false;
    end

    local transId = grid.trans_id;
    local exchangeId = query(transId, "exchange");

    grid.trans_id = exchangeId;

    -- 抛出元素转换事件
    EventMgr.fire(event.TRANS_ELIMINATE_CHANGE, {["pos"] = pos});

    return true;
end

-- 当前是否还存在转换消除元素
function hasTransEliminate()
    local grids = DungeonM.getCurrentDungeon() or {};
    for _, grid in pairs(grids) do
        if grid.type == GRID_TYPE_TRANS_ELIMINATE and
            grid.state ~= GRID_STATE_DISABLE then
            return true;
        end
    end

    return false;
end

-- 检查全清
function checkAllClear()
    local grids = DungeonM.getCurrentDungeon() or {};
    for _, grid in pairs(grids) do
        if grid.type == GRID_TYPE_TRANS_ELIMINATE and
            grid.state ~= GRID_STATE_DISABLE then
            local transId = grid.trans_id;
            local clear = query(transId, "clear");

            if type(clear) == "number" and clear ~= 1 then
                -- 当前还有非清除元素
                return;
            end
        end
    end

    -- 所有元素置为失效
    local dieGrids = {};
    for _, grid in pairs(grids) do
        if grid.type == GRID_TYPE_TRANS_ELIMINATE then
            -- 改变状态
            grid:changeState(GRID_STATE_DISABLE);
            table.insert(dieGrids, grid:getPos());
        end
    end

    DungeonServiceM.monsterClear();

    DarkStoneM.darkStoneDisable();

    -- 开门
    SkyInstanceM.openDoor();

    -- 抛出通关事件
    EventMgr.fire(event.TRANS_ELIMINATE_PASSED, {["grids"] = dieGrids});
end